import { Color, Sprite, _decorator, Label, instantiate, Graphics } from 'cc';
import { EntityManager } from '../../framework/base/EntityManager';
import { ITower } from '../../src/shared/common/Interface';
import { EEntity, EStatus } from '../../src/shared/common/Enum';
import { CEntityShadeColor, DEBUG } from '../../common/Contsant';
import { ObjectPoolManager } from '../../framework/ObjectPoolManager';
import { createUINode } from '../../utils/Util';
import { RenderData } from '../../gameRender/RenderData';
import ResManager, { EPath } from '../../runtime/ResManager';
import { RenderManager } from '../../gameRender/RenderManager';
import { towerMachine } from './towerMachine';
import { ExcelManager } from '../../runtime/ExcelManager';

const { ccclass, property } = _decorator;

@ccclass('enemyEntity')
export class towerEntity extends EntityManager {
    entityType: number;

    /** 正在播放死亡动画 */
    playingDieAnim: boolean = false
    /** 死亡标记 */
    isDead: boolean = false
    init(tower: ITower) {
        this.addBody()
        this.setBodyMaterial()
        this.fsm = this.node.addComponent(towerMachine)
        this.fsm.init(tower)
    }

    reset(tower: ITower) {
        const { entityType, atkDis } = tower
        this.entityType = entityType
        this.state = EStatus.idle
        this.node.setScale(3, 3)
        this.isDead = false

        if (DEBUG) {
            const graphicsNode = this.node.getChildByName('graphicsNode') || createUINode('graphicsNode')
            graphicsNode.parent = this.node
            const g = graphicsNode.getComponent(Graphics) || graphicsNode.addComponent(Graphics)
            g.circle(0, 0, atkDis)
            g.lineWidth = 10;
            g.stroke()

            const labNode = this.node.getChildByName('labNode') || createUINode('labNode')
            labNode.parent = this.node
            const lab = labNode.getComponent(Label) || labNode.addComponent(Label)
            lab.string = '' + tower.id
        }
    }

    render(tower: ITower) {
        if (this.isDead) return
        const { status, id } = tower
        if (status == EStatus.dead) {
            this.isDead = true
            this.deleteShowUI(id)
            return
        }
        if (status != EStatus.idle) {
            this.state = status
        }
        this.showBornEff(tower)
        const { x, y } = RenderManager.Ins.getTowerPosById(tower.x, tower.y, tower.id)
        this.showShadow(tower, x, y)
        this.setPos(tower, x, y)
    }

    /** 位置 */
    setPos(tower: ITower, x: number, y: number) {
        let { atkDir } = tower
        this.node.setPosition(x, y)
        if (atkDir == 1) {
            this.node.scale_x = -Math.abs(this.node.scale_x)
        } else if (atkDir == 0) {
            this.node.scale_x = Math.abs(this.node.scale_x)
        }
    }

    /** 播放原来的效果 */
    playOriginalEffect() {
        const sprite = this.body.getComponent(Sprite)
        sprite.color = new Color(...CEntityShadeColor.Normal)
    }

    /** 显示阴影 */
    showShadow(tower: ITower, x: number, y: number) {
        const { id, entityType } = tower
        if (!RenderData.Ins.shadow2id[id]) {
            RenderData.Ins.shadow2id[id] = ObjectPoolManager.Ins.poolAllocByStr(EPath.shadow)
            if (!RenderData.Ins.shadow2id[id]) {
                RenderData.Ins.shadow2id[id] = instantiate(ResManager.Ins.getPrefabByPath(EPath.shadow))
                RenderData.Ins.shadow2id[id].parent = RenderManager.Ins.shadowArea
            }
            RenderData.Ins.shadow2id[id].active = true
            const color = this.getShadowColor(entityType)
            RenderData.Ins.shadow2id[id].uiSprite.color = new Color(color)
        }
        RenderData.Ins.shadow2id[id].setPosition(x, y - 30)
    }

    deleteShowUI(id: number) {
        ObjectPoolManager.Ins.poolFree(this)
        RenderData.Ins.tower2id[id] = null

        ObjectPoolManager.Ins.poolFreeByStr(EPath.shadow, RenderData.Ins.shadow2id[id])
        RenderData.Ins.shadow2id[id] = null
    }

    /** 品质 1:白 2:绿 3:蓝 4:紫 5:橙 6:红  */
    getShadowColor(entityType: EEntity) {
        ExcelManager.Ins.tableTower.init(entityType)
        switch (ExcelManager.Ins.tableTower.quality) {
            case 1: return new Color(200, 200, 200, 200)
            case 2: return new Color(100, 200, 100, 200)
            case 3: return new Color(100, 200, 200, 200)
            case 4: return new Color(200, 100, 200, 200)
            case 5: return new Color(200, 200, 100, 200)
            case 6: return new Color(200, 100, 100, 200)
        }
        return new Color(0)
    }


    /** 出生特效 */
    showBornEff(tower: ITower) {
        const { x, y, status } = tower
        if (status == EStatus.born) {
            RenderManager.Ins.showBornLab(x, y)
        }
    }
}